<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    const arr = [[1, 2], [[3, 4], [5, 6], [[7, 8, 9], [10, 11, 12, 13, [14, {
        age: 15
    }], [16, 17, 18]]]]]

    // 使用reduce
    const flatten1 = (arr) => {
        return arr.reduce((pre, cur) => {
            return pre.concat(Array.isArray(cur) ? flatten1(cur) : cur)
        }, [])
    }

    const flatten2 = (arr) => {
        let result = []
        for (let i = 0, len = arr.length; i < len; i++) {
            let item = arr[i]
            if (Array.isArray(item)) {
                result = result.concat(flatten2(item))
            } else {
                result.push(item)
            }
        }
        return result
    }

    // 利用扩展运算符 [...[1,2],...[3,4,5]] >>> [1,2,3,4,5]的性质
    const flatten3 = (arr) => {
        while (arr.some(item => Array.isArray(item))) {
            arr = [].concat(...arr)
        }
        return arr
    }

    // toString() 可以将数组转换成字符串，但是不适用于数组元素为对象！如果元素均为Number类型的才适用
    const flatten4 = (arr) => {
        return arr.toString().split(',')
    }

    // flat() 是ES2019的新特性， 默认就是第一层，Infinity代表所有层
    const flatten5 = (arr) => {
        return arr.flat(Infinity)
    }

    // 先使用JSON.stringify方法转换成字符串，再利用正则去掉括号，最后用JSON.parse转换成数组
    const flatten6 = (arr) => {
        let str = JSON.stringify(arr);
        str = str.replace(/(\[|\])/g, '');
        str = `[${str}]`;
        return JSON.parse(str);
    };

    // 前三种适合元素为对象的，后三种适合元素为Number类型的
    console.log("flatten1:", flatten1(arr))
    console.log("flatten2:", flatten2(arr))
    console.log("flatten3:", flatten3(arr))

    console.log("flatten4:", flatten4(arr))
    console.log("flatten5:", flatten4(arr))
    console.log("flatten6:", flatten4(arr))


</script>
</body>
</html>
